package com.eryos.android.cigarettecounter.tool;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.util.Log;

/**
 * Project : CigaretteCounter Author : Olivier Combe URL : http://eryos.fr/CigaretteCounter/
 * 
 * Copyright(C)2011 - Olivier Combe
 * 
 * Licensed under the Apache License, Version 2.0(the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
 * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations under the License.
 * 
 * @version \$Revision.*\$
 * @author Olivier Combe
 */
public class LogReporterInterface {

    /** Log Levels. */
    public enum LogLevel {
        VERBOSE, DEBUG, INFO, WARNING, ERROR, ALL
    }

    /** ******************* Static Constants. ******************* **/
    private static final String ACTION_REPORT = "com.eryos.android.logreporter.action.REPORT_LOG";
    private static final String LOG_REPORTER = "com.eryos.android.logreporter";

    /** EXTRA_EMAIL Tag. */
    public static final String EXTRA_EMAIL = "com.eryos.android.logreporter.tag.EXTRA_EMAIL";
    /** EXTRA_EMAIL_CC Tag. */
    public static final String EXTRA_EMAIL_CC = "com.eryos.android.logreporter.tag.EXTRA_EMAIL_CC";
    /** EXTRA_EMAIL_BCC Tag. */
    public static final String EXTRA_EMAIL_BCC = "com.eryos.android.logreporter.tag.EXTRA_EMAIL_BCC";
    /** EXTRA_SUBJECT Tag. */
    public static final String EXTRA_SUBJECT = "com.eryos.android.logreporter.tag.EXTRA_SUBJECT";
    /** EXTRA_MESSAGE Tag. */
    public static final String EXTRA_MESSAGE = "com.eryos.android.logreporter.tag.EXTRA_MESSAGE";
    /** EXTRA_FILTERS Tag. */
    public static final String EXTRA_FILTERS = "com.eryos.android.logreporter.tag.EXTRA_FILTERS";
    /** EXTRA_ADVANCED_FILTERS Tag. */
    public static final String EXTRA_ADVANCED_FILTERS = "com.eryos.android.logreporter.tag.EXTRA_ADVANCED_FILTERS";
    /** EXTRA_MAX_LINES Tag. */
    public static final String EXTRA_MAX_LINES = "com.eryos.android.logreporter.tag.EXTRA_MAX_LINES";
    /** EXTRA_DEBUG_INFO Tag. */
    public static final String EXTRA_DEBUG_INFO = "com.eryos.android.logreporter.tag.EXTRA_DEBUG_INFO";

    /** LineReturn constant. */
    public static final String LINE_RETURN = "\n";
    /** LineReturn separator. */
    public static final String LINE_SEPARATOR = LINE_RETURN + "-------------------------------------" + LINE_RETURN;

    /** ******************* Instance Variables. ******************* **/
    private final List<String> emailList;
    private final List<String> emailListCC;
    private final List<String> emailListBCC;
    private final List<String> logFilterList;
    private String subject = "";
    private String message = "";
    private String debugInfo = "";
    private int maxLineNumbers = 1000;
    private final Context context;
    private final Map<String, String> filters;

    private final Intent logIntent;

    private final boolean toolInstalled;

    /**
     * LogReporterIntent.
     * 
     * @param _ctx
     *            : context that will be used to create dialog box
     */
    public LogReporterInterface(Context _ctx) {
        logIntent = new Intent(ACTION_REPORT);
        Log.d("LogReporterInterface", "new LogReporterInterface()");

        context = _ctx;

        emailList = new ArrayList<String>();
        emailListCC = new ArrayList<String>();
        emailListBCC = new ArrayList<String>();
        logFilterList = new ArrayList<String>();
        filters = new HashMap<String, String>();

        toolInstalled = checkLogReporterInstalled();
        if (!toolInstalled) {

            Log.d("LogReporterInterface", "Show dialog Box");

            /* show a message */
            Builder dialog = new AlertDialog.Builder(context);
            dialog.setTitle("Download LogReporter tool ?");
            dialog.setIcon(android.R.drawable.ic_dialog_info);
            dialog.setMessage("You need to install 'Log Reporter Tool' " + "(free and open source tool)"
                    + "to process this operation. " + "Are you agree ?");
            dialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(final DialogInterface dialog, final int whichButton) {
                    Log.d("LogReporterInterface", "Click Dialog Box");
                    downloadLogReporterApk();
                }
            });
            dialog.setNegativeButton("Cancel", null);
            dialog.show();
        } else {
            Log.d("LogReporterInterface", "APK Available");
        }
    }

    /**
     * Start the LogReporter.
     */
    public void start() {
        if (toolInstalled) {
            Log.d("LogReporterInterface", "Start activity");
            context.startActivity(logIntent);
        }
    }

    /**
     * Method used to check if the LogReporter Application is already installed or not For this, the application try to
     * find the default action to process the current intent, if there is no default action, the LogReporter app is not
     * yet installed.
     * 
     * @return true if the application is already installed on the device
     */
    private boolean checkLogReporterInstalled() {
        List<ResolveInfo> list = context.getPackageManager().queryIntentActivities(logIntent,
                PackageManager.MATCH_DEFAULT_ONLY);
        boolean res = list.size() > 0;
        Log.d("LogReporterInterface", "Available app : " + res);
        return res;
    }

    /**
     * Method used to raise a new intent(Android Market destination)to download. the LogReporter application
     */
    private void downloadLogReporterApk() {
        Log.d("LogReporterInterface", "downloadApk");

        Intent downloadIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("market://search?q=pname:" + LOG_REPORTER));
        downloadIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(downloadIntent);
    }

    /**
     * @param subjectArg
     *            to send
     */
    public void setMailSubject(final String subjectArg) {
        subject = subjectArg;
        logIntent.putExtra(EXTRA_SUBJECT, subject);
    }

    /**
     * @param messageArg
     *            to send
     */
    public void setMailMessage(final String messageArg) {
        message = messageArg;
        logIntent.putExtra(EXTRA_MESSAGE, message);
    }

    /**
     * @param mail
     *            recipient
     */
    public void addMailRecipient(final String mail) {
        emailList.add(mail);
        logIntent.putExtra(EXTRA_EMAIL, emailList.toArray(new String[emailList.size()]));
    }

    /**
     * @param mail
     *            copy recipient
     */
    public void addMailCopyRecipient(final String mail) {
        emailListCC.add(mail);
        logIntent.putExtra(EXTRA_EMAIL_CC, emailListCC.toArray(new String[emailListCC.size()]));
    }

    /**
     * @param mail
     *            hidden recipient
     */
    public void addMailHiddenRecipient(final String mail) {
        emailListBCC.add(mail);
        logIntent.putExtra(EXTRA_EMAIL_BCC, emailListBCC.toArray(new String[emailListBCC.size()]));
    }

    /**
     * @param tag
     *            to filter
     */
    public void addLogFilter(final String tag) {
        logFilterList.add(tag);
        logIntent.putExtra(EXTRA_FILTERS, logFilterList.toArray(new String[logFilterList.size()]));
    }

    /**
     * @param max
     *            number of lines to report
     */
    public void setMaxLogLines(final int max) {
        maxLineNumbers = max;
        logIntent.putExtra(EXTRA_MAX_LINES, maxLineNumbers);
    }

    /**
     * @param debug
     *            information to send
     */
    public void setDebugInfo(final String debug) {
        debugInfo = debug;
        logIntent.putExtra(EXTRA_DEBUG_INFO, debugInfo);
    }

    /**
     * @param logTag
     *            LogTag to filter
     * @param logLevel
     *            LogLevel to filter
     */
    public void addLogFilter(final String logTag, final LogLevel logLevel) {
        filters.put(logTag, logLevel.toString());
        logIntent.putExtra(EXTRA_ADVANCED_FILTERS, (HashMap<String, String>) filters);

        addLogFilter(logTag);
    }
}
